package com.supermarket.service;

import com.supermarket.entity.DTO.OrderDTO;
import com.supermarket.entity.Order;
import com.supermarket.entity.OrderItem;
import com.supermarket.mapper.OrderItemMapper;
import com.supermarket.mapper.OrderMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.supermarket.common.RedisUtil;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.HashMap;
import java.util.Set;

/**
 * 订单Service实现类
 */
@Service
public class OrderService {

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private OrderItemMapper orderItemMapper;
    
    @Autowired
    private RedisUtil redisUtil;
    
    // Redis缓存相关的Key前缀
    private static final String ORDER_DETAIL_KEY = "order:detail:";
    private static final String ORDER_USER_KEY = "order:user:";
    private static final String ORDER_NO_KEY = "order:no:";
    private static final String ORDER_LIST_KEY = "order:list";
    private static final int ORDER_CACHE_SECONDS = 1800; // 订单缓存默认30分钟

    /**
     * 创建订单
     * @param order 订单信息
     * @param orderItems 订单商品明细列表
     * @return 订单信息
     */
    @Transactional
    public Order createOrder(Order order, List<OrderItem> orderItems) {
        // 生成唯一订单号
        String orderNo = generateOrderNo();
        order.setOrderNo(orderNo);
        // 如果订单状态为空，则设置为默认状态
        if (order.getStatus() == null) {
            order.setStatus("PENDING_PAYMENT"); // 默认待付款状态
        }
        order.setCreateTime(new Date());
        order.setUpdateTime(new Date());
        order.setVersion(0);
        
        // 保存订单
        orderMapper.insertOrder(order);
        
        // 设置订单项的订单ID并计算小计金额
        for (OrderItem item : orderItems) {
            item.setOrderId(order.getId());
            // 小计 = 单价 * 数量
            item.setSubtotal(item.getCommodityPrice().multiply(java.math.BigDecimal.valueOf(item.getQuantity())));
        }
        
        // 批量保存订单项
        orderItemMapper.batchInsertOrderItems(orderItems);
        
        // 清除用户订单列表缓存
        clearUserOrderCache(order.getUserId());
        
        return order;
    }
    
    /**
     * 生成唯一订单号
     * @return 订单号
     */
    private String generateOrderNo() {
        // 时间戳+随机数
        return System.currentTimeMillis() + UUID.randomUUID().toString().substring(0, 6);
    }
    
    /**
     * 根据ID查询订单
     * @param id 订单ID
     * @return 订单信息
     */
    public OrderDTO getOrderById(Integer id) {
        String cacheKey = ORDER_DETAIL_KEY + id;
        
        // 尝试从缓存获取
        Object cached = redisUtil.get(cacheKey);
        if (cached != null) {
            return (OrderDTO) cached;
        }
        
        // 缓存未命中，查询数据库
        OrderDTO order = orderMapper.selectOrderById(id);
        
        // 将结果存入缓存
        if (order != null) {
            redisUtil.set(cacheKey, order, ORDER_CACHE_SECONDS);
        }
        
        return order;
    }
    
    /**
     * 根据订单号查询订单
     * @param orderNo 订单号
     * @return 订单信息
     */
    public OrderDTO getOrderByOrderNo(String orderNo) {
        String cacheKey = ORDER_NO_KEY + orderNo;
        
        // 尝试从缓存获取
        Object cached = redisUtil.get(cacheKey);
        if (cached != null) {
            return (OrderDTO) cached;
        }
        
        // 缓存未命中，查询数据库
        OrderDTO order = orderMapper.selectOrderByOrderNo(orderNo);
        
        // 将结果存入缓存
        if (order != null) {
            redisUtil.set(cacheKey, order, ORDER_CACHE_SECONDS);
        }
        
        return order;
    }
    
    /**
     * 查询用户的所有订单
     * @param userId 用户ID
     * @return 订单列表
     */
    public List<OrderDTO> getOrdersByUserId(Integer userId) {
        String cacheKey = ORDER_USER_KEY + userId;
        
        // 尝试从缓存获取
        Object cached = redisUtil.get(cacheKey);
        if (cached != null) {
            return (List<OrderDTO>) cached;
        }
        
        // 缓存未命中，查询数据库
        List<OrderDTO> orders = orderMapper.selectOrdersByUserId(userId);
        
        // 将结果存入缓存
        if (orders != null && !orders.isEmpty()) {
            redisUtil.set(cacheKey, orders, ORDER_CACHE_SECONDS);
        }
        
        return orders;
    }
    
    /**
     * 查询用户特定状态的订单
     * @param userId 用户ID
     * @param status 订单状态
     * @return 订单列表
     */
    public List<OrderDTO> getOrdersByUserIdAndStatus(Integer userId, String status) {
        String cacheKey = ORDER_USER_KEY + userId + ":" + status;
        
        // 尝试从缓存获取
        Object cached = redisUtil.get(cacheKey);
        if (cached != null) {
            return (List<OrderDTO>) cached;
        }
        
        // 缓存未命中，查询数据库
        List<OrderDTO> orders = orderMapper.selectOrdersByUserIdAndStatus(userId, status);
        
        // 将结果存入缓存
        if (orders != null) {
            redisUtil.set(cacheKey, orders, ORDER_CACHE_SECONDS);
        }
        
        return orders;
    }
    
    /**
     * 根据条件分页查询订单
     * @param status 订单状态
     * @param orderNo 订单编号
     * @param pageNum 页码
     * @param pageSize 每页数量
     * @return 包含订单列表和总数的Map
     */
    public Map<String, Object> getOrdersWithCondition(String status, String orderNo, int pageNum, int pageSize) {
        String cacheKey = generateOrderListCacheKey(status, orderNo, pageNum, pageSize);
        
        // 尝试从缓存获取
        Object cached = redisUtil.get(cacheKey);
        if (cached != null) {
            return (Map<String, Object>) cached;
        }
        
        // 缓存未命中，查询数据库
        int offset = (pageNum - 1) * pageSize;
        List<OrderDTO> orders = orderMapper.selectOrdersWithCondition(status, orderNo, offset, pageSize);
        int total = orderMapper.countOrdersWithCondition(status, orderNo);
        
        Map<String, Object> result = new HashMap<>();
        result.put("list", orders);
        result.put("total", total);
        
        // 将结果存入缓存，设置较短的过期时间
        redisUtil.set(cacheKey, result, 600); // 10分钟
        
        return result;
    }
    
    /**
     * 取消订单
     * @param orderNo 订单号
     * @return 是否成功
     */
    @Transactional
    public boolean cancelOrder(String orderNo) {
        Date now = new Date();
        OrderDTO order = getOrderByOrderNo(orderNo);
        
        // 只有待付款状态的订单可以取消
        if (order != null && "PENDING_PAYMENT".equals(order.getStatus())) {
            boolean success = orderMapper.cancelOrder(order.getId(), now) > 0;
            
            if (success) {
                // 清除相关缓存
                clearOrderCache(order.getId(), orderNo, order.getUserId());
            }
            
            return success;
        }
        return false;
    }
    
    /**
     * 支付订单
     * @param id 订单ID
     * @return 是否成功
     */
    @Transactional
    public boolean payOrder(Integer id) {
        Date now = new Date();
        OrderDTO order = getOrderById(id);
        
        // 只有待付款状态的订单可以支付
        if (order != null && "PENDING_PAYMENT".equals(order.getStatus())) {
            int result = orderMapper.payOrder(id, now);
            // 更新订单状态为已付款
            if (result > 0) {
                boolean success = orderMapper.updateOrderStatus(id, "PAID", now) > 0;
                
                if (success) {
                    // 清除相关缓存
                    clearOrderCache(id, order.getOrderNo(), order.getUserId());
                }
                
                return success;
            }
        }
        return false;
    }
    
    /**
     * 发货
     * @param id 订单ID
     * @return 是否成功
     */
    @Transactional
    public boolean shipOrder(Integer id) {
        Date now = new Date();
        OrderDTO order = getOrderById(id);
        
        // 判断订单状态和支付方式
        if (order != null) {
            boolean canShip = "PAID".equals(order.getStatus()) || 
                             ("PENDING_PAYMENT".equals(order.getStatus()) && "CASH".equals(order.getPaymentType()));
            
            if (canShip) {
                int result = orderMapper.shipOrder(id, now);
                // 更新订单状态为已发货
                if (result > 0) {
                    boolean success = orderMapper.updateOrderStatus(id, "SHIPPED", now) > 0;
                    
                    if (success) {
                        // 清除相关缓存
                        clearOrderCache(id, order.getOrderNo(), order.getUserId());
                    }
                    
                    return success;
                }
            }
        }
        return false;
    }
    
    /**
     * 完成订单
     * @param id 订单ID
     * @return 是否成功
     */
    @Transactional
    public boolean completeOrder(Integer id) {
        Date now = new Date();
        OrderDTO order = getOrderById(id);
        
        // 只有已发货的订单可以完成
        if (order != null && "SHIPPED".equals(order.getStatus())) {
            int result = orderMapper.completeOrder(id, now);
            // 更新订单状态为已完成
            if (result > 0) {
                boolean success = orderMapper.updateOrderStatus(id, "COMPLETED", now) > 0;
                
                if (success) {
                    // 清除相关缓存
                    clearOrderCache(id, order.getOrderNo(), order.getUserId());
                }
                
                return success;
            }
        }
        return false;
    }
    
    /**
     * 分页查询所有订单
     * @param pageNum 页码
     * @param pageSize 每页数量
     * @return 订单列表
     */
    public List<OrderDTO> getOrdersWithPagination(int pageNum, int pageSize) {
        String cacheKey = ORDER_LIST_KEY + ":page" + pageNum + ":size" + pageSize;
        
        // 尝试从缓存获取
        Object cached = redisUtil.get(cacheKey);
        if (cached != null) {
            return (List<OrderDTO>) cached;
        }
        
        // 缓存未命中，查询数据库
        int offset = (pageNum - 1) * pageSize;
        List<OrderDTO> orders = orderMapper.selectOrdersWithPagination(offset, pageSize);
        
        // 将结果存入缓存，设置较短的过期时间
        if (orders != null && !orders.isEmpty()) {
            redisUtil.set(cacheKey, orders, 600); // 10分钟
        }
        
        return orders;
    }
    
    /**
     * 统计订单总数
     * @return 订单总数
     */
    public int countOrders() {
        String cacheKey = "order:count";
        
        // 尝试从缓存获取
        Object cached = redisUtil.get(cacheKey);
        if (cached != null) {
            return (int) cached;
        }
        
        // 缓存未命中，查询数据库
        int count = orderMapper.countOrders();
        
        // 将结果存入缓存，设置较短的过期时间
        redisUtil.set(cacheKey, count, 600); // 10分钟
        
        return count;
    }
    
    /**
     * 统计某一天的订单数
     * @param date 日期，格式为yyyy-MM-dd
     * @return 订单数
     */
    public int countOrdersByDate(String date) {
        String cacheKey = "order:count:" + date;
        
        // 尝试从缓存获取
        Object cached = redisUtil.get(cacheKey);
        if (cached != null) {
            return (int) cached;
        }
        
        // 缓存未命中，查询数据库
        int count = orderMapper.countOrdersByDate(date);
        
        // 将结果存入缓存
        redisUtil.set(cacheKey, count, 600); // 10分钟
        
        return count;
    }
    
    /**
     * 获取订单详情DTO
     * @param orderId 订单ID
     * @return 订单详情DTO
     */
    public OrderDTO getOrderDTOById(Integer orderId) {
        return getOrderById(orderId);
    }
    
    /**
     * 生成订单列表缓存Key
     */
    private String generateOrderListCacheKey(String status, String orderNo, int pageNum, int pageSize) {
        StringBuilder sb = new StringBuilder(ORDER_LIST_KEY);
        sb.append(":page").append(pageNum);
        sb.append(":size").append(pageSize);
        
        if (status != null && !status.isEmpty()) {
            sb.append(":status").append(status);
        }
        if (orderNo != null && !orderNo.isEmpty()) {
            sb.append(":no").append(orderNo);
        }
        
        return sb.toString();
    }
    
    /**
     * 清除订单缓存
     */
    private void clearOrderCache(Integer id, String orderNo, Integer userId) {
        // 清除订单详情缓存
        if (id != null) {
            redisUtil.delete(ORDER_DETAIL_KEY + id);
        }
        
        // 清除订单号缓存
        if (orderNo != null) {
            redisUtil.delete(ORDER_NO_KEY + orderNo);
        }
        
        // 清除用户订单缓存
        clearUserOrderCache(userId);
        
        // 清除订单列表缓存
        Set<String> listKeys = redisUtil.keys(ORDER_LIST_KEY + "*");
        if (listKeys != null && !listKeys.isEmpty()) {
            redisUtil.delete(listKeys);
        }
        
        // 清除订单计数缓存
        redisUtil.delete("order:count");
        
        // 清除日期计数缓存
        Set<String> dateKeys = redisUtil.keys("order:count:*");
        if (dateKeys != null && !dateKeys.isEmpty()) {
            redisUtil.delete(dateKeys);
        }
    }
    
    /**
     * 清除用户订单缓存
     */
    private void clearUserOrderCache(Integer userId) {
        if (userId != null) {
            // 清除用户订单列表
            redisUtil.delete(ORDER_USER_KEY + userId);
            
            // 清除用户按状态分类的订单列表
            Set<String> statusKeys = redisUtil.keys(ORDER_USER_KEY + userId + ":*");
            if (statusKeys != null && !statusKeys.isEmpty()) {
                redisUtil.delete(statusKeys);
            }
        }
    }
}
